const classNames = require('classnames')
const _ = require('../utils')
const constants = require('../constants')
const { listParentBehavior, listItemBehavior } = require('../behaviors')

const animSize = 60

_.create('popup', {
  options: {
    multipleSlots: true, // 在组件定义时的选项中启用多slot支持
  },

  data: {
    visibility: 'hidden',
  },

  properties: {
    title: { type: String, value: '' },
    show: { type: Boolean, value: false },
    position: { type: String, value: 'center' },
    closable: { type: Boolean, value: true },
    maskClosable: { type: Boolean, value: true },
    mask: { type: Boolean, value: true },
    bordered: Boolean,
    draggable: { type: Boolean, value: false },
    duration: { type: Number, value: 350 },
  },

  behaviors: [listParentBehavior],

  relations: {
    listItem: {
      type: 'child',
      target: listItemBehavior,

      linked() {
        this.assignElementSN('listItem')
      },
      linkChanged() {
        this.assignElementSN('listItem')
      },
      unlinked() {
        this.assignElementSN('listItem')
      },
    },
  },

  computed: {
    classes: function (data) {
      const { draggable, classPrefix, bordered } = data
      const classes = classNames(classPrefix, `${classPrefix}-position`, {
        [`${classPrefix}-draggable`]: draggable,
        [`${classPrefix}-bordered`]: bordered,
      })

      return classes
    },
  },

  observers: {
    show: function (show) {
      const { visibility } = this.data

      if (show && visibility === 'hidden') {
        this.setData({ visibility: 'visible' })
        wx.nextTick(() => this._animIn())
      } else if (visibility === 'visible') {
        this._animOut()
      }
    },
  },

  methods: {
    _animIn() {
      // const easeOut = 'ease-out'
      const keyframes = [
        { opacity: 0, translateY: animSize, ease: constants.animation.easeOutQuad },
        { opacity: 1, translateY: 0, ease: constants.animation.easeOutQuad },
      ]
      this.animate('#mp-popup-container', keyframes, this.data.duration, () => {
        this.triggerEvent('show')
        this.clearAnimation('#mp-popup-container', { translateY: true })
      })
    },

    _animOut(origin = 0, offset = animSize) {
      const keyframes = [
        {
          opacity: 1,
          translateY: origin,
          ease: constants.animation.easeInQuad,
        },
        { opacity: 0, translateY: offset, ease: constants.animation.easeInQuad },
      ]
      this.animate('#mp-popup-container', keyframes, this.data.duration, () => {
        this.setData({ visibility: 'hidden' })
        this.clearAnimation('#mp-popup-container')
        this.triggerEvent('hide')
      })
    },

    onMaskTap(e) {
      if (!this.data.maskClosable) return
      const query = this.createSelectorQuery()
      query.select('#mp-popup-container').boundingClientRect()
      query.exec((res) => {
        const { left, right, top, bottom } = res[0]
        const { x, y } = e.detail

        if (x > left && x < right && y > top && y < bottom) return
        this.close()
      })
    },

    show() {
      this.setData({ show: true })
    },

    close() {
      this.setData({ show: false })
    },

    onTouchStart(e) {
      if (!e.changedTouches || !this.data.draggable) return
      this.startY = e.changedTouches[0].pageY
    },

    onTouchMove(e) {
      if (!e.changedTouches || !this.data.draggable) return
      const { pageY } = e.changedTouches[0]
      const offsetY = pageY - this.startY
      this.setData({
        translate: `transform: translateY(${offsetY * 2}rpx);`,
      })
    },

    onTouchEnd(e) {
      if (!e.changedTouches || !this.data.draggable) return
      const { pageY } = e.changedTouches[0]
      const offsetY = pageY - this.startY

      if (Math.abs(offsetY) > 40) {
        const d = offsetY > 0 ? offsetY + 50 : offsetY - 50
        this._animOut(offsetY, d)
        this.close()
      }
      this.setData({ translate: '' })
    },
  },
})
